//1. 并没有立即执行  而是得到了返回值 返回值就是一个函数 执行这个函数 原函数才会被执行
//2. 参数 : 有两部分组成 1. bind后面的参数  2. 返回的函数的参数
//3. 返回值 返回原函数的返回值 
//4. new 返回的函数的时候  此时的返回值就指向返回函数的实例 (前提是返回的函数的返回值不是引用类型)
//5. 如果是引用类型 就会返回 原函数的返回值

//args1 : bind后面的参数
Function.prototype.selfBind = function (target,...args1){
  // console.log(this) // 谁调用就指向谁 
  const func = this;
  // func : abc这个函数
  // 返回值 : 是什么 ? 返回的是一个函数
  //boundFunc : 代表的就是 Fn
  const boundFunc = function(...args2){
    // 1. 将参数合并
    const args = [...args1,...args2];
    // 2. 判断new还是没new
    if(new.target){ // new了
      let res = func.apply(this,args);
      if((typeof res  === 'object' || 'function' )&& res !== null){
        return res;
      }else{
        return this;
      }
    }else{ // 没new
      return func.apply(target,args);
    }
    // 3. 将this指向target
    // 4. 处理返回值
  }
  return boundFunc;
}

function abc(...args){
  this.q = 'params'
  console.log(this,args)
  return {pp:'pp'}
}

const Fn = abc.selfBind({a:123},1,2,3,4)
// console.log(Fn(7,8,9,10))
const res = new Fn(7,8,9,10)
console.log(res)